/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bakenote;

//import sync.WebDavInterface;
//import sound.WavPlayer;

import bakenote.data.RecipeGroupList;
import bakenote.data.RecipeSQLiteDB;
import bakenote.data.RecipeList;
import bakenote.ui.BakeNoteWindow;
import bakenote.ui.ErrorOpen;
import org.apache.pivot.beans.BXMLSerializer;
import org.apache.pivot.collections.Map;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.wtk.*;
import org.apache.pivot.xml.Element;
import org.apache.pivot.xml.TextNode;
import org.apache.pivot.xml.XMLSerializer;

import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

//import java.awt.Toolkit;


/**
 * @author lello
 */
public class BakeNote implements Application {

    private static BakeNoteWindow window = null;
    private static RecipeSQLiteDB rdb = null;
    private static BXMLSerializer bxmlSerializer = new BXMLSerializer();
    private static boolean dbOK = false;

    private static String userHome = System.getProperty("user.home");
    private static String bakeNoteStorageDirectory = userHome + File.separator + ".bakenote";
    private static String configFileName = bakeNoteStorageDirectory + File.separator + "config.xml";

    public BakeNote() {
        // No-op
    }

    @Override
    public void startup(Display display, Map<String, String> properties) throws Exception {
        // if the connection to the database has been successfully established we can open the UI
        window = (BakeNoteWindow) bxmlSerializer.readObject(BakeNote.class, "ui/bakenote_window.bxml");
        window.open(display);
    }

    @Override
    public boolean shutdown(boolean optional) {
        if (window != null) {
            window.close();
            rdb.close();
        }
        return false;
    }

    @Override
    public void suspend() {
    }

    @Override
    public void resume() {
        /** No-op **/
    }

    public static void main(String[] args) {

        BakeNote.checkResources();

        // Initialize the groups of recipes
        RecipeGroupList.init();
        // Initialize the recipe HashMap
        RecipeList.init();

        // check that the database file exists
        try {
            rdb = new RecipeSQLiteDB(bakeNoteStorageDirectory);
            // if the database exists connect
            if (rdb.exist()) {
                try {
                    rdb.connect();
                    RecipeSQLiteDB.loadRecipes();
                    RecipeSQLiteDB.loadGroups();
                    dbOK = true;
                } catch (SQLException ex) {
                    dbOK = false;
                }
            } else {
                // if the database does not exists then create it  using the sql script files.
                try {
                    rdb.create();
                    rdb.init();
                    dbOK = true;
                } catch (SQLException ex) {
                    dbOK = false;
                    Logger.getLogger(BakeNote.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(BakeNote.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (dbOK) {
            DesktopApplicationContext.main(BakeNote.class, args);
        } else {
            String[] myArgs = {"--width=300", "--height=150", "--resizable=false", "--center=true"};
            DesktopApplicationContext.main(ErrorOpen.class, myArgs);
        }

    }


    private static void checkResources() {

        File configFile = new File(configFileName);

        XMLSerializer xmlSerializer = new XMLSerializer();

        if (configFile.exists() && configFile.canRead()) {
            // if we have a configuration we load it
            try {
                Element element = xmlSerializer.readObject(new FileInputStream(configFile));
                bakeNoteStorageDirectory =  element.getElements("database").get(0).getText();
                if (bakeNoteStorageDirectory.isEmpty()) {
                    System.out.println("Missing database directory. Check your configuration file.");
                    System.exit(0);
                }
            } catch (IOException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (SerializationException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        } else {
            File configDirectory = new File(bakeNoteStorageDirectory);
            // create the configuration directory if it doesn't exist
            if (!configDirectory.exists()) configDirectory.mkdirs();
            if (!configFile.exists()) try {
                configFile.createNewFile();
                Element configElement = new Element("configuration");
                Element databaseElement = new Element("database");
                TextNode databaseName = new TextNode(bakeNoteStorageDirectory);
                databaseElement.add(databaseName);
                configElement.add(databaseElement);

                // Write the recipeBook to a stringWriter for later indentation
                StringWriter stringWriter = new StringWriter();
                xmlSerializer.writeObject(configElement, stringWriter);

                // Apply indentation to the stringWriter
                Transformer transformer = TransformerFactory.newInstance().newTransformer();
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");

                StringWriter indentedStringWriter = new StringWriter();
                transformer.transform(new StreamSource(new StringReader(stringWriter.toString())), new StreamResult(indentedStringWriter));
                // Save the xml element to a file
                FileWriter fw = new FileWriter(configFile, true);
                fw.write(indentedStringWriter.toString());
                fw.flush();
                fw.close();
            } catch (IOException e) {
                System.out.println("cannot create configuration file.");
                //e.printStackTrace();
            } catch (TransformerException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (SerializationException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

    public static String getStorageDirectory() {
        return bakeNoteStorageDirectory;
    }

    public static String getFileStorageDirectory() {
        return bakeNoteStorageDirectory+File.separator+"storage";
    }

}
